# -*- coding: utf-8 -*-
# Created by huangqiyin on 2017/12/6

import logging

from sanic import response
from utils.mongo import get_app_config_collection
from utils.util import _render_template, merge_conf
from sanic import Blueprint
from appconfigsvr.auth.permission import permission_check, get_permission, PERMISSION

bp = Blueprint('config', url_prefix='')
_logger = logging.getLogger(__name__)


def get_app_env_key(app_name, env):
    return "config::%s::%s" % (app_name, env)


@bp.post('/config')
async def add_app_template(request):
    try:
        _json = request.json
        app_name = _json["app_name"]
        yaml_str = _json["template"]

        _logger.info("app_name %s env %s config %s host %s", app_name, yaml_str, request.host)
        get_app_config_collection().find_one_and_update({"app_name": app_name},
                                                              {"$set": _json},
                                                              upsert=True)

    except Exception as e:
        _logger.exception("url %s" % request.url)
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "", "data": {}})


# @bp.post('/app_env_config')
# async def add_app_env_config(request):
#     try:
#         _json = request.json
#         app_name = _json["app_name"]
#         env = _json["env"]
#         env_config = _json["env_config"]

#         _logger.info("app_name %s env %s config %s host %s", app_name, env, env_config, request.host)

#         _update = {"env_config_%s" % (env): env_config}
#         get_app_config_collection().find_one_and_update({"app_name": app_name},
#                                                               {"$set": _update},
#                                                               upsert=True)
#     except Exception as e:
#         _logger.exception("url %s" % request.url)
#         _logger.exception(e)
#         return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
#     else:
#         return response.json({"code": 0, "message": "", "data": {}})


@bp.post('/app_env_config')
async def add_app_env_config(request):
    try:
        _json = request.json
        app_name = _json["app_name"]
        env = _json["env"]
        env_config = _json["env_config"]

        _logger.info("app_name %s env %s config %s host %s", app_name, env, env_config, request.host)

        _update = {"env_config_%s" % (env): env_config}
        get_app_config_collection().find_one_and_update({"app_name": app_name},
                                                              {"$set": _update},
                                                              upsert=True)
    except Exception as e:
        _logger.exception("url %s" % request.url)
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "", "data": {}})


@bp.post('/app_global_template')
async def add_app_global_template(request):
    try:
        _json = request.json
        app_name = _json["app_name"]
        global_template_name = _json["global_template1"]

        _logger.info("app_name %s host %s", app_name, request.host)

        _update = {"global_template.%s" % (global_template_name): 1}
        get_app_config_collection().find_one_and_update({"app_name": app_name},
                                                              {"$set": _update},
                                                              upsert=True)
    except Exception as e:
        _logger.exception("url %s" % request.url)
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "", "data": {}})


@bp.delete('/app_global_template')
async def remove_app_global_template(request):
    try:
        _json = request.json
        app_name = _json["app_name"]
        global_template_name = _json["global_template1"]

        _logger.info("app_name %s host %s", app_name, request.host)
        try:
            app_config = get_app_config_collection().find_one({"app_name": app_name})
        except Exception as e:
            _logger.exception(e)
        else:
            if app_config:
                global_templates = app_config['global_template']
                if global_template_name in global_templates:
                    del global_templates[global_template_name]
                _update = {"global_template": global_templates}
                get_app_config_collection().find_one_and_update({"app_name": app_name},
                                                                      {"$set": _update},
                                                                      upsert=True)
    except Exception as e:
        _logger.exception("url %s" % request.url)
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "", "data": {}})


@bp.get("/config_list")
async def app_config_list(request):
    try:
        app_name = request.raw_args.get("app_name", "")
        page = int(request.raw_args.get("page", 1))
        limit = int(request.raw_args.get("limit", 30))
        tag = request.raw_args.get("tag", "")

        _where = {"app_name": {"$regex": app_name}}
        if tag and tag != "null" and tag != "全部":
            _where.update({"tag": tag})
        cur = get_app_config_collection().find(_where, {"_id": 0})
        print(dir(cur))
        _count= cur.count()

        cur.skip((page - 1) * limit).limit(limit)
        res = []
        for doc in cur:
            res.append(doc)

        return response.json(
            {"code": 0, "message": "", "data": res, "count": _count})
    except Exception as e:
        _logger.exception("url %s" % request.url)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.get("/tag")
async def tag(request):
    try:
        res = get_app_config_collection().distinct("tag", )

        return response.json(
            {"code": 0, "message": "", "data": {"tagList": res}, })
    except Exception as e:
        _logger.exception("url %s" % request.url)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.delete('/config')
async def remove_app_config(request):
    try:
        app_name = request.raw_args['app_name']
        _logger.info("app_name %s host %s", app_name, request.host)
        get_app_config_collection().delete_one({"app_name": app_name})
    except Exception as e:
        _logger.exception("url %s" % request.url)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "remove ok", "data": {}})


@bp.get("/get_rendered_app_config")
async def get_rendered_app_config(request):
    try:
        app_name = request.raw_args.get("app_name", "")
        env = request.raw_args.get("env", "")
        doc = get_app_config_collection().find_one({"app_name": app_name}, {"_id": 0})
        _conf = await merge_conf(doc, env)
        render_str = _conf[env]
        return response.json({"code": 0, "message": "", "data": render_str, })
    except Exception as e:
        _logger.exception("url %s" % request.url)
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "", "data": {}})


@bp.post("/render_template")
async def render_template(request):
    try:
        _json = request.json
        template_data = _json["template"]
        env = _json["env"]
        app_name = _json["app_name"]
        render_str = await _render_template(template_data, env, app_name)
        return response.json({"code": 0, "message": "", "data": render_str, })

    except Exception as e:
        _logger.exception("url %s" % request.url)
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})
    else:
        return response.json({"code": 0, "message": "", "data": {}})
